/*
 * cpu_xml.h
 *
 *  Created on: 2008-10-28
 *      Author: root
 */

#ifndef CPU_XML_H_
#define CPU_XML_H_

#include "cxml.h"

//#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

class CPU_XML: public CXML
{
public:
	CPU_XML();
	virtual ~CPU_XML()
	{
	}

	void setCPU(float);
	void setMem(int);
	virtual void formXML(char *);

	float getCPU();
	int getMem();
	virtual void readDetail(const char *);
	virtual void formReqSQL(char *);
	virtual void formStoreSQL(char *);
	virtual int query(sqlite3 *);
	virtual int store(sqlite3 *);
	virtual void formCID(unsigned char *);

private:
	float cpu;
	int mem;
};

CPU_XML::CPU_XML()
{
	mem = 0;
	cpu = 0.0;
}

void CPU_XML::setCPU(float cpuv)
{
	cpu = cpuv;
}

void CPU_XML::setMem(int memv)
{
	mem = memv;
}

float CPU_XML::getCPU()
{
	return cpu;
}

int CPU_XML::getMem()
{
	return mem;
}

void CPU_XML::formXML(char *buf)
{
	char strTmp[128];
	//	time_t curTime;
	//	time(&curTime);
	TiXmlDocument xmlDoc;//("cpu_memory.xml"); // 建立一个XML文件
	TiXmlDeclaration Declaration("1.0", "UTF-8", "yes"); // 声明XML的属性
	xmlDoc.InsertEndChild(Declaration); // 写入基本的XML头结构
	TiXmlNode * pNode = NULL;
	TiXmlElement* pRootElm = NULL;
	TiXmlElement* pChildElm1 = NULL;
	TiXmlElement* pChildElm2 = NULL;
	TiXmlText* pText = NULL; // 一个指向Text的指针

	pRootElm = new TiXmlElement(title);
	pRootElm->SetAttribute("msgType", type);
	pNode = xmlDoc.InsertEndChild(*pRootElm); // first level (root), xmlDoc insert it

	pRootElm = pNode->ToElement();

	pChildElm1 = new TiXmlElement("operation");
	if (reqId)
		pChildElm1->SetAttribute("requestorId", reqId);
	pText = new TiXmlText(oper);
	pChildElm1->InsertEndChild(*pText); // child level 1
	pRootElm->InsertEndChild(*pChildElm1);
	delete pChildElm1;
	delete pText;

	pChildElm1 = new TiXmlElement("nodeId");
	pText = new TiXmlText(nid);
	pChildElm1->InsertEndChild(*pText);
	pRootElm->InsertEndChild(*pChildElm1);
	delete pText;
	delete pChildElm1;

	pChildElm1 = new TiXmlElement("details");

	pNode = pRootElm->InsertEndChild(*pChildElm1);
	pRootElm = pNode->ToElement();

	pChildElm2 = new TiXmlElement("time"); // child level 2
	sprintf(strTmp, "%d", time);
	pText = new TiXmlText(strTmp);
	pChildElm2->InsertEndChild(*pText);
	pRootElm->InsertEndChild(*pChildElm2);
	delete pText;
	delete pChildElm2;

	pChildElm2 = new TiXmlElement("cpu");
	sprintf(strTmp, "%.1f", (float) cpu);
	pText = new TiXmlText(strTmp);
	pChildElm2->InsertEndChild(*pText);
	pRootElm->InsertEndChild(*pChildElm2);
	delete pText;
	delete pChildElm2;

	pChildElm2 = new TiXmlElement("memory");
	sprintf(strTmp, "%d", mem);
	pText = new TiXmlText(strTmp);
	pChildElm2->InsertEndChild(*pText);
	pRootElm->InsertEndChild(*pChildElm2);
	delete pText;
	delete pChildElm2;

	TiXmlPrinter printer;
	xmlDoc.Accept(&printer);
	strcpy(buf, printer.CStr());

	//return (printer.CStr());

	//	int t = printer.Size() + 1; // the size of useful string
	//	char *a = (char *) malloc(t);
	//	strcpy(a, printer.CStr());
	//	printf("%s \n", a);
}

void CPU_XML::readDetail(const char *info)
{
	assert(info != NULL);

	TiXmlDocument doc;
	doc.Parse(info);

	TiXmlElement *rootElem;
	TiXmlElement *pElem;

	rootElem = doc.RootElement();
	if (!rootElem)
	{
		printf("Error in parsing XML string!\n");
		exit(1);
	}

	pElem = rootElem->FirstChildElement("details");
	rootElem = pElem->ToElement();
	pElem = rootElem->FirstChildElement("time");
	//cout << pElem->GetText()<< endl;							//1225264523
	setTime(atoi(pElem->GetText()));
	pElem = rootElem->FirstChildElement("cpu");
	//cout << pElem->GetText()<< endl;							//98.0
	setCPU(atof(pElem->GetText()));
	pElem = rootElem->FirstChildElement("memory");
	//cout << pElem->GetText()<< endl;							//8236
	setMem(atoi(pElem->GetText()));

}

void CPU_XML::formReqSQL(char *sql)
{
	sprintf(
			sql,
			"select nodeId, cpu, memory, ctime from resourceInfo where nodeId = %s "
				"and ctime = (select max(ctime) from resourceInfo where nodeId = %s)",
			nid, nid);
}

void CPU_XML::formStoreSQL(char *sql)
{
	sprintf(
			sql,
			"INSERT INTO resourceInfo(nodeId, cpu, memory, ctime) VALUES('%s', '%f', '%d', '%d')",
			nid, cpu, mem, time);
}

/*
 * 返回查询结果的数据，0即没查到，＞0即查到
 */
int CPU_XML::query(sqlite3 *pDB)
{
	char sql[256];
	char **azResult, *errMsg;
	int nrow, ncolumn;

	sprintf(
			sql,
			"select nodeId, cpu, memory, ctime from resourceInfo where nodeId = %s "
				"and ctime = (select max(ctime) from resourceInfo where nodeId = %s)",
			nid, nid);

	/*
	 * 查询用sqlite3_get_table，结果通过数组azResult保存，
	 * 内容是先是表格头部名称，接着才是查出来的数据
	 * nrow为查出来的结果数目，为0时表示数据库中不存在符合条件的记录
	 * ncolumn为表格头的域数
	 */

	sqlite3_get_table(pDB, sql, &azResult, &nrow, &ncolumn, &errMsg);
	if (nrow > 0)
	{
		printf("Locally matched \n");
		//setNID(azResult[ncolumn]);
		setCPU(atof(azResult[ncolumn + 1]));
		setMem(atoi(azResult[ncolumn + 2]));
		setTime(atoi(azResult[ncolumn + 3]));
		setOper("reply");
		setTitle("ContextResponse");
		setType("resourceInfo");
	}
	sqlite3_free_table(azResult);
	return nrow;
}

int CPU_XML::store(sqlite3 *pDB)
{
	char sql[256];
	char *errMsg;
	int rc;
	sprintf(
			sql,
			"INSERT INTO resourceInfo(nodeId, cpu, memory, ctime) VALUES('%s', '%f', '%d', '%d')",
			nid, cpu, mem, time);
	rc = sqlite3_exec(pDB, sql, 0, 0, &errMsg);
	if (rc != SQLITE_OK)
		printf("Error: %d...%s\n", rc, errMsg);

	return rc;
}

void CPU_XML::formCID(unsigned char *cid)
{
	memcpy(cid, nid, IDLENV/2);
	strcpy((char *)(cid + IDLENV / 2), "cpu");
}

#endif /* CPU_XML_H_ */
